﻿//TODO: Test

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public class MedialAxisTransform : BaseForeBackgroundColorFilter
    {
        protected int m_nThreshold = 1;

        /// <summary>
        /// Initializes a new instance of the <see cref="MedialAxisTransform"/> class.
        /// </summary>
        public MedialAxisTransform()
        {
        }

        /// <summary>
        /// Sets threshold at initialization time
        /// </summary>
        /// <param name="_nThreshold"></param>
        public MedialAxisTransform(int _nThreshold)
        {
            m_nThreshold = _nThreshold;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MedialAxisTransform"/> class.
        /// </summary>
        /// <param name="_medialAxisTransform">The _medial axis transform.</param>
        internal MedialAxisTransform(MedialAxisTransform _medialAxisTransform)
        {
            m_nThreshold = _medialAxisTransform.m_nThreshold;
        }

        /// <summary>
        /// Gets or sets Threshold value
        /// </summary>
        public int Threshold
        {
            get { return m_nThreshold; }
            set { m_nThreshold = value; }
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap binary = new DistanceTransform().Execute(_bitmap); //(binary, scale, offset);
            int[,] greyLevel = new int[binary.Width, binary.Height];
            for (int n = 0; n < binary.Height; ++n)
            {
                for (int m = 0; m < binary.Width; ++m)
                {
                    greyLevel[m, n] = binary[m, n].ToArgb();
                    if (binary[m, n] != m_ColorBackground)
                        binary[m, n] = m_ColorForeground;
                }
            }
            binary = new Skeletonize().Execute(binary);
            if (m_nThreshold != 0) //if !m_nThreshold
            {
                for (int n = 0; n < binary.Height; ++n)
                {
                    for (int m = 0; m < binary.Width; ++m)
                    {
                        if (binary[m, n] == m_ColorForeground)  //?! was stand hier vorher?
                        {
                            int g = Color.FromArgb(greyLevel[m, n]).R;
                            g = (int)Math.Round(g * m_fScale + m_fOffset);
                            if (g > 255) g = 255;
                            if (g < 0) g = 0;

                            binary[m, n] = Color.FromArgb(greyLevel[m, n]);
                        }
                    }
                }
            }
            for (int y = 0; y < _bitmap.Height; y++)
            {
                for (int x = 0; x < _bitmap.Width; x++)
                {
                    _bitmap[x, y] = binary[x, y];
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new MedialAxisTransform(this);
        }
    }
}
